import apis from '../http'
import moment from '../moment/index.js' // 日期处理类库

// 服务端签名客户端直传方式

const upload = {
	policy: null,		  	  // web直传使用的policy子签名
	expire: '',	  			  // 过期时间
	ossClient: null,          // oss客户端实例
	expiration: '',        // 过期时间
	ossUrl: '',               // oss url路径地址前缀

	// 请求服务端签名客户端直传使用的policy签名
	async initPolicy() {
		// 获取oss配置
		let res = await apis.getOssPolicy()
		if (res && res.code === 200 && res.data) {
			// 获取过期时间
			this.expire = res.data.
				res.data.host = res.data.host?.endsWith('/') ? res.data.host.slice(0, res.data.host.length - 1) : res.data.host
			this.policy = res.data
		} else {
			uni.showToast({
				icon: 'none',
				position: 'center',
				duration: 2000,
				title: '请求Web直传使用的policy子签名失败'
			})
		}
	},
	async uploadFile(file, path, watchUploadInfo = null, watchUploadInfoFunc = null) {
		return new Promise(async (resolve, reject) => {
			path = path.endsWith('/') ? path : `${ path }/`
			path = path.startsWith('/') ? path : `/${path}`
			if (this.expire && moment(this.expire).subtract(1, 'minute').isBefore(moment())) {
				console.log(`policySign 将在 1 分钟内过期，重新获得policySign后继续上传`)
				await this.initPolicy()
			}
			if (!this.policy) {
				await this.initPolicy()
			}
			let fileName = await this.getFileName(file)
			let formData = {
				'OSSAccessKeyId': this.policy.accessId,    		// 获取到的accessId
				'policy': this.policy.policy,					// 获取到的policy
				'signature': this.policy.signature,				// 获取到的签名
				'key': `${ path }${ fileName }`,      				// 获取到的dir再加文件名拼接
				'success_action_status': '200'					// 设置上传成功返回的状态码，默认是204
			}
			if (this.policy.callback != undefined) {
				formData['callback'] = this.policy.callback	// 如果有回调，那一并传至oss
			}
			let uploadTask = uni.uploadFile({
				url: this.policy.host,
				filePath: file,   // filePath可以是base64，也可以是blob url
				name: 'file',
				formData: formData,
				success: (res) => {
					if (watchUploadInfo) watchUploadInfo.percent = 100
					if (watchUploadInfoFunc) watchUploadInfoFunc(100)
					if (res.statusCode !== 200) {
						reject(res)
					} else {
						console.log('上传成功，返回结果：', res)
						resolve(this.policy.host + path + fileName)
					}
				},
				fail: (err) => {
					// console.log('uploadImage fail', err);
					// uni.showModal({
					// 	content: err.errMsg,
					// 	showCancel: false
					// });
					reject(err)
				}
			})
			uploadTask.onProgressUpdate((res) => {
				// console.log("上传进度" + res.progress);
				if (watchUploadInfo) watchUploadInfo.percent = parseInt(res.progress * 100 + '', 10)
				if (watchUploadInfoFunc) watchUploadInfoFunc(res.progress)

			})
		})
	},
	// 随机生成一个文件名
	async getFileName(file) {
		let fileObj = null
		if (typeof (file) === 'string' && file.indexOf('base64') >= 0) {
			// 如果是base64，转为Blob对象
			fileObj = await this.dataUrl2BlobObj(file)
			return moment().format('YYYYMMDD-hhmmss') + '-' + parseInt(Math.random() * 1000000) + '.' + fileObj.type.split('/')[1]
		} else if (typeof (file) === 'string' && file.indexOf('blob') >= 0) {
			// 如果是blobUrl，转为Blob对象
			fileObj = await this.blobUrl2BlobObj(file)
			return moment().format('YYYYMMDD-hhmmss') + '-' + parseInt(Math.random() * 1000000) + '.' + fileObj.type.split('/')[1]
		} else {
			return moment().format('YYYYMMDD-hhmmss') + '-' + parseInt(Math.random() * 1000000) + file.slice(file.lastIndexOf('.'))
		}
	},

	// base64转Blob对象
	async dataUrl2BlobObj(dataurl) {
		return new Promise((resolve, reject) => {
			let arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
				bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n)
			while (n--) {
				u8arr[n] = bstr.charCodeAt(n)
			}
			let blob = new Blob([u8arr], {type: mime})
			resolve(blob)
		})
	},

	// blobUrl转Blob对象
	async blobUrl2BlobObj(url) {
		return new Promise((resolve, reject) => {
			const xhr = new XMLHttpRequest()
			xhr.open('GET', url, true)
			xhr.responseType = 'blob'
			xhr.onload = function (e) {
				if (this.status == 200) {
					let Blob = this.response
					resolve(Blob)
				}
			}
			xhr.send()
		})
	},
}

export default upload
